/**
 * 
 */
package weka;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;

import java.io.File;
import java.util.Enumeration;
import java.util.Random;

import JFlex.Out;

import weka.classifiers.Classifier;
import weka.classifiers.Evaluation;
import weka.classifiers.evaluation.EvaluationUtils;
import weka.classifiers.trees.J48;
import weka.classifiers.trees.J48_KNN;
import weka.core.FastVector;
import weka.core.Instance;
import weka.core.Instances;
import weka.core.converters.ConverterUtils.DataSource;

/**
 * @author user
 *
 */
public class Try1 extends J48_KNN{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public static void main2(String[] args){
		ClassifiersInterface intf = new ClassifiersTester();
		InterfaceReturnValue ret = intf.testClassifierOnDatabase("/Users/user/Documents/Masters/courses/236756Learning/required_datasets/zoo.arff", "weka.classifiers.trees.J48_KNN", "-E -U -M 10 -L -P -K 6");
		if(ret.hadError()){
			System.out.println(ret.getErrorDescription());
		}
		System.out.println("Accuracy: "+ret.getAccuracy());
		System.out.println("ErrorRate: "+ret.getErrorRate());
		System.out.println("ConfusionMatrix: ");
		printConfusionMatrix(ret);
		
	}
	
	
	
	private static void printConfusionMatrix(InterfaceReturnValue ret) {
		double[][] confusionMatrix = ret.getConfusionMatrix();
		String[] labels = ret.getTargetClassLabels();
		int max = 0;
		for(String name : labels){
			if(max<name.length()){
				max = name.length();
			}
		}

		System.out.printf("%"+(max+2)+"s"," ");
		for(String name : labels){
			System.out.printf("%"+max+"s",name);
		}
		
		
		for (int i=0; i<confusionMatrix.length; ++i){
			double[] row = confusionMatrix[i];
			System.out.println();
			System.out.printf("%"+max+"s",labels[i]);
			for (int j=0; j<row.length; ++j){
				System.out.printf("% " + max +".2f   ",confusionMatrix[i][j]);
			}			
		}
		
	}

	
	public static void main(String[] args){
		try{
			
			
		// set data
		DataSource source = new DataSource("/Users/user/Documents/Masters/courses/236756Learning/required_datasets/lenses.arff"); 
		Instances data = source.getDataSet(); data.setClassIndex(data.numAttributes() - 1);
		// create a decision-tree classifier
		/*	IBk classifier = new IBk();
    	String[] options = weka.core.Utils.splitOptions("-K 1 -W 0 -A \"weka.core.neighboursearch.LinearNNSearch -A \\\"weka.core.EuclideanDistance -R first-last\\\"\"");
    	
    	*/
		String[] options1 = weka.core.Utils.splitOptions(" -P -U -B -M 10 -K 3");
		J48_KNN classifier1 = new J48_KNN();

		classifier1.setOptions(options1);

		EvaluationUtils eval = new EvaluationUtils(); 
		eval.setSeed(17);
		FastVector f = eval.getCVPredictions(classifier1, data, 10);
		
		
		}catch(Exception e){
			Out.println("exception Thrown !!!");
			e.printStackTrace();
		}
		
	}




	public static void main5(String[] args){
		try{
			
			
		// set data
		DataSource source = new DataSource("/Users/user/Documents/Masters/courses/236756Learning/required_datasets/lenses.arff"); 
		Instances data = source.getDataSet(); data.setClassIndex(data.numAttributes() - 1);
		// create a decision-tree classifier
    /*	IBk classifier = new IBk();
    	String[] options = weka.core.Utils.splitOptions("-K 1 -W 0 -A \"weka.core.neighboursearch.LinearNNSearch -A \\\"weka.core.EuclideanDistance -R first-last\\\"\"");
    	
    	*/
		String[] options1 = weka.core.Utils.splitOptions(" -P -U -B -M 10 -K 3");
		J48_KNN classifier1 = new J48_KNN();

		classifier1.setOptions(options1);
		System.out.println("K for KNN = " + classifier1.getKForKNN());

				
		evalClassifier(data, classifier1);
		// unpruned tree
		// new instance of tree // set the options
		// run cross-validation
		classifier1.buildClassifier(data);
		Enumeration<Instance> e = data.enumerateInstances();
		for(int i=1; i<3 && e.hasMoreElements(); i++){
			Instance ins = e.nextElement();
			System.out.println(classifier1.classifyInstance(ins));
		}
		
		String[] options2 = weka.core.Utils.splitOptions("-U -B -M 10 -K 3");
		J48_KNN classifier2 = new J48_KNN();

		classifier2.setOptions(options2);
		System.out.println("K for KNN = " + classifier2.getKForKNN());
		// unpruned tree
		// new instance of tree // set the options
		// run cross-validation
		classifier2.buildClassifier(data);
		 e = data.enumerateInstances();
		for(int i=1; i<3 && e.hasMoreElements(); i++){
			Instance ins = e.nextElement();
			System.out.println(classifier2.classifyInstance(ins));
		}

		//classifier1.setUsePartOffeaturesForKNN(true);
		
		/*e = data.enumerateInstances();
		
		for(int i=1; i<30 && e.hasMoreElements(); i++){
			Instance ins = e.nextElement();
			System.out.println(i +" : " +classifier.classifyInstance(ins));
		}
		
		classifier.setUsePartOffeaturesForKNN(false);
		
		
		for(int i=1; i<30 && e.hasMoreElements(); i++){
			Instance ins = e.nextElement();
			System.out.println(i +" : " +classifier.classifyInstance(ins));
		}
		
		*/
		
		
//		classifier.setUsePartOffeaturesForKNN(true);
		evalClassifier(data, classifier2);
		}catch(Exception e){
			Out.println("exception Thrown !!!");
			e.printStackTrace();
		}
		
	}

	
	private static void printStringArray(String[] arr){
		for(String s : arr){
			System.out.print(s + " ");
		}
}

	private static void evalClassifier(Instances data, Classifier classifier)
			throws Exception {
		EvaluationUtils eval = new EvaluationUtils(); 
		FastVector f = eval.getCVPredictions(classifier, data, 10);
		System.out.println(classifier.getOptions());
		System.out.println(classifier.toString());
		printStringArray(classifier.getOptions());
		System.out.println(f.toString());
	}
	/**
	 * @param args
	 */
	public static void main3(String[] args) {
		J48_KNN tree = new J48_KNN();
		//String[] databases = getDataBases("required_datasets");

		
	//	for(String database : databases){
		
// -t arff file to parse
		//-g  print graph
		//-L
		//-C
		//-M
			String[] options = ("-t ../../required_datasets/nursery.arff -g -L -C 0.25 -M 2").split(" "); 

			
			
			
			//Instances instances = null;
		//	tree.buildClassifier(instances);

			Classifier.runClassifier(tree, options);
		
			String graph = null;
			
			try {
				graph = tree.graph();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.print(graph);
			Instances inst = null;
		//}
		
			FileWriter fstream;
			try {
				fstream = new FileWriter("out.txt");
				BufferedWriter out = new BufferedWriter(fstream);
				tree.graph(out);
				out.write(tree.toString());
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			  
		runClassifier(tree, args);
		
		System.out.println(tree.toString());

	}
	
	static String[] getDataBases(String file){
		File dir = new File(file);
		
		FilenameFilter filter = new FilenameFilter() {
			
			@Override
			public boolean accept(java.io.File dir, String name) {
				// TODO Auto-generated method stub
				return name.toLowerCase().endsWith("arff");
			}
						
		};
		if(! dir.exists()) {
			throw new RuntimeException("Couldn't find " + file);
		}
		
		File[] children = dir.listFiles(filter);

		String[] filenames = new String[children.length];
		for(int i = 0 ; i<children.length; ++i){
			filenames[i] = children[i].getAbsolutePath();
		}
		return filenames;
		
	}
	
	Instances getInstancesFromFile(String rttfFileName){
		try {
			DataSource trainSource = new DataSource(rttfFileName);

			return trainSource.getDataSet();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}
	

}
